package com.ds.app.database;

import com.ds.app.*;
import com.ds.common.cache.CacheSizes;
import com.ds.common.cache.Cacheable;
import com.ds.common.logging.Log;
import com.ds.common.logging.LogFactory;
import com.ds.org.*;
import com.ds.org.conf.OrgConfig;
import com.ds.org.conf.OrgConstants;
import com.ds.server.OrgManagerFactory;
import com.ds.server.eumus.ConfigCode;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

public class DbApp implements App, Cacheable, Serializable, Comparable<App> {
    protected static Log log = LogFactory.getLog(OrgConstants.CONFIG_KEY.getType(), DbApp.class);
    private ConfigCode configCode;
    private String ID;
    private Integer index = 0;
    private String name;
    private String enName;
    private String icon;
    private String parentId;
    public boolean moduleIdList_is_initialized;
    boolean childIdList_is_initialized;

    private List childIdList;
    private List recursiveChildIdList;
    private List moduleIdList;
    private List recursiveModuleIdList;

    private Integer tier;

    private String brief;
    private boolean appIdList_is_initialized;
    private Object appIdList;

    private List<String> personIdList;
    boolean personIdList_is_initialized;

    private List<String> orgIdList;
    boolean orgIdList_is_initialized;

    private List<String> disablePersonIdList;
    boolean disablePersonIdList_is_initialized;

    private List<String> roleIdList;
    boolean roleIdList_is_initialized;
 
    private DBAppDataBaseManager dbAppManager;

    private OrgConfig getConfig() {

	OrgConfig config = OrgConfig.getInstance(this.configCode);
	return config;
    }

    DbApp(ConfigCode configCode) {
	if (configCode == null) {
		configCode = OrgConstants.CONFIG_KEY;
	}
	this.dbAppManager = DBAppDataBaseManager.getInstance(configCode);
	this.configCode = configCode;
    }

    public String getID() {
	return ID;
    }

    public String getBrief() {

	return brief;
    }

    public List<String> getChildIdList() {
	prepareChildren();
	if (childIdList == null) {
	    return new ArrayList<String>();
	}
	return childIdList;
    }

    public List<App> getChildrenList() {
	prepareChildren();
	if (childIdList == null) {
	    return new ArrayList<App>();
	}
	List<App> childList = new ArrayList<App>();
	AppCacheManager cacheManager = AppCacheManager.getInstance(this.configCode);
	for (int i = 0, n = childIdList.size(); i < n; i++) {
	    try {
		childList.add(cacheManager.getAppByID((String) childIdList.get(i)));
	    } catch (AppNotFoundException ex) {
	    }
	}
	return childList;
    }

    public List<String> getChildIdsRecursivelyList() {
	if (recursiveChildIdList == null) {
	    recursiveChildIdList = new ArrayList<String>();
	    List<App> appList = this.getChildrenList();
	    for (int i = 0; i < appList.size(); i++) {
		recursiveChildIdList.add(appList.get(i).getID());
		List<App> temp = appList.get(i).getChildrenRecursivelyList();
		for (int j = 0; j < temp.size(); j++) {
		    recursiveChildIdList.add(temp.get(j).getID());
		}
	    }
	}

	return recursiveChildIdList;
    }

    public List<App> getChildrenRecursivelyList() {
	if (recursiveChildIdList == null) {
	    getChildIdsRecursivelyList();
	}
	List<App> childList = new ArrayList<App>();
	AppCacheManager cacheManager = AppCacheManager.getInstance(this.configCode);
	for (int i = 0, n = recursiveChildIdList.size(); i < n; i++) {
	    try {
		childList.add(cacheManager.getAppByID((String) recursiveChildIdList.get(i)));
	    } catch (AppNotFoundException ex) {
	    }
	}
	return childList;

    }

    public List<String> getModuleIdList() {
	prepareModules();
	if (moduleIdList == null) {
	    return new ArrayList();
	}
	return moduleIdList;
    }

    public List<Module> getModuleList() {
	prepareModules();
	List<Module> moduleList = new ArrayList<Module>();
	if (moduleIdList == null) {
	    return moduleList;
	}
	AppCacheManager cacheManager = AppCacheManager.getInstance(this.configCode);
	for (int i = 0, n = moduleIdList.size(); i < n; i++) {
	    try {
		moduleList.add(cacheManager.getModuleByID((String) moduleIdList.get(i)));
	    } catch (ModuleNotFoundException ex) {
	    }
	}
	return moduleList;
    }

    public String getName() {
	return name;
    }

    public App getParent() {
	try {
	    return AppCacheManager.getInstance(this.configCode).getAppByID(parentId);
	} catch (AppNotFoundException ex) {
	    return null;
	}
    }

    public List<App> getAllParent() {

	List<App> result = new ArrayList<App>();
	App parent = this.getParent();
	result.add(parent);
	while (parent != null) {
	    App p = parent.getParent();
	    if (p != null) {
		result.add(p);
	    }
	    parent = p;
	}
	return result;
    }

    public String getParentId() {
	return parentId;
    }

    public List<String> getModuleIdListRecursively() {
	if (recursiveModuleIdList == null) {
	    Set moduleSet = new LinkedHashSet();
	    List<String> moduleList = this.getModuleIdList();
	    // 加上本应用的模块
	    for (int i = 0; i < moduleList.size(); i++) {
		moduleSet.add(moduleList.get(i));
	    }
	    // 加上子应用的模块
	    List<App> appList = getChildrenRecursivelyList();
	    for (int i = 0; i < appList.size(); i++) {
		App app = appList.get(i);
		List<Module> cmoduleList = app.getModuleList();
		for (Module module : cmoduleList) {
		    moduleSet.add(module.getID());
		}
	    }
	    recursiveModuleIdList = new ArrayList<String>(moduleSet);
	}

	return recursiveModuleIdList;
    }

    public List<Module> getModuleListRecursively() {
	if (recursiveModuleIdList == null) {
	    getModuleIdListRecursively();
	}

	List<Module> moduleList = new ArrayList<Module>();
	AppCacheManager cacheManager = AppCacheManager.getInstance(this.configCode);
	for (int i = 0, n = recursiveModuleIdList.size(); i < n; i++) {
	    try {
		moduleList.add(cacheManager.getModuleByID((String) recursiveModuleIdList.get(i)));
	    } catch (ModuleNotFoundException ex) {
	    }
	}
	return moduleList;
    }

  

    // 增加角色
    public void addRole(String roleId) {
	if (roleIdList == null) {
	    roleIdList = new ArrayList();
	}
	this.roleIdList.add(roleId);
    }

    // 增加具有权限使用人员
    public void addPerson(String personId) {
	if (personIdList == null) {
	    personIdList = new ArrayList();
	}
	this.personIdList.add(personId);
    }

    // 增加具有权限使用人员
    public void addOrg(String personId) {
	if (orgIdList == null) {
	    orgIdList = new ArrayList();
	}
	this.orgIdList.add(personId);
    }

    // 禁用人员
    public void addDisablePerson(String personId) {
	if (disablePersonIdList == null) {
	    disablePersonIdList = new ArrayList();
	}
	this.disablePersonIdList.add(personId);
    }

    // 增加子应用
    public void addChild(String childId) {
	if (childIdList == null) {
	    childIdList = new ArrayList();
	}
	childIdList.add(childId);
    }

    // 增加模块
    public void addModule(String moduleId) {
	if (moduleIdList == null) {
	    moduleIdList = new ArrayList();
	}
	moduleIdList.add(moduleId);
    }

    /**
     * 判断子应用是否已载入，如果未载入则载入
     */
    private void prepareChildren() {
	if (!childIdList_is_initialized) {
	    dbAppManager.loadChildren(this);
	}
    }

    /**
     * 判断模块是否已载入，如果未载入则载入
     */
    private void prepareModules() {
	if (!moduleIdList_is_initialized) {

	    dbAppManager.loadModules(this);

	}
    }

    /**
     * 判断人员是否已载入，如果未载入则载入
     */
    private void preparePersons() {
	if (!personIdList_is_initialized) {

	    dbAppManager.loadPersons(this);

	}
    }

    /**
     * 判断人员是否已载入，如果未载入则载入
     */
    private void prepareOrgs() {
	if (!orgIdList_is_initialized) {

	    dbAppManager.loadOrgs(this);

	}
    }

    /**
     * 判断禁用人员是否已载入，如果未载入则载入
     */
    private void prepareDisablePersons() {
	if (!disablePersonIdList_is_initialized && getConfig().isSupportPersonDuty()) {

	    dbAppManager.loadDisablePersons(this);

	}
    }

  

    /**
     * 判断岗位是否已载入，如果未载入则载入
     */
    private void preparePositions() {
	if (!appIdList_is_initialized && getConfig().isSupportPersonPosition()) {

	    dbAppManager.loadPositions(this);

	}
    }

    /**
     * 判断角色是否已载入，如果未载入则载入
     */
    private void prepareRoles() {
	if (!appIdList_is_initialized && getConfig().isSupportPersonRole()) {

	    dbAppManager.loadRoles(this);

	}
    }

    public List<Person> getDisablePersonList() {

	prepareDisablePersons();
	if (disablePersonIdList == null) {
	    return new ArrayList<Person>();
	}
	List<Person> personList = new ArrayList<Person>();
		OrgManager cacheManager =OrgManagerFactory.getOrgManager();
	for (int i = 0, n = disablePersonIdList.size(); i < n; i++) {
	    try {
		personList.add(cacheManager.getPersonByID((String) disablePersonIdList.get(i)));
	    } catch (PersonNotFoundException ex) {
	    }
	}
	return personList;
    }

    public List<Person> getPersonList() {
	preparePersons();
	if (personIdList == null) {
	    return new ArrayList<Person>();
	}
	List<Person> personList = new ArrayList<Person>();
		OrgManager cacheManager =OrgManagerFactory.getOrgManager();
	for (int i = 0, n = personIdList.size(); i < n; i++) {
	    try {
		personList.add(cacheManager.getPersonByID((String) personIdList.get(i)));
	    } catch (PersonNotFoundException ex) {
	    }
	}
	return personList;
    }

    public List<Org> getOrgList() {
	prepareOrgs();
	if (orgIdList == null) {
	    return new ArrayList<Org>();
	}
	List<Org> orgList = new ArrayList<Org>();
		OrgManager cacheManager =OrgManagerFactory.getOrgManager();
	for (int i = 0, n = orgIdList.size(); i < n; i++) {
	    try {
		orgList.add(cacheManager.getOrgByID((String) orgIdList.get(i)));
	    } catch (OrgNotFoundException ex) {
	    }
	}
	return orgList;
    }

    public List<String> getOrgIdList() {
	prepareOrgs();
	if (orgIdList == null) {
	    return new ArrayList<String>();
	}
	return orgIdList;
    }

    

    public List<String> getRoleIdList() {
	prepareRoles();
	if (roleIdList == null) {
	    return new ArrayList();
	}
	return roleIdList;
    }

    public List<Role> getRoleList() {
	prepareRoles();
	if (roleIdList == null) {
	    return new ArrayList();
	}
	List personRoleList = new ArrayList();
		OrgManager cacheManager =OrgManagerFactory.getOrgManager();
	for (int i = 0, n = roleIdList.size(); i < n; i++) {
	    try {
		personRoleList.add(cacheManager.getRoleByID((String) roleIdList.get(i)));
	    } catch (RoleNotFoundException ex) {
	    }
	}
	return personRoleList;
    }

    public List<Person> getRightPersonList() {
	List<Person> personList = new ArrayList<Person>();
	
	List<Role> roleList = this.getRoleList();
	for (int k = 0; k < roleList.size(); k++) {
	    Role role = roleList.get(k);
	    List<Person> dpersonList = role.getPersonList();
	    for (int i = 0; i < dpersonList.size(); i++) {
		Person person = dpersonList.get(i);
		if (!personList.contains(person)) {
		    personList.add(person);
		}
		;
	    }
	}
	
	List<Org> orgList = this.getOrgList();
	for (int k = 0; k < orgList.size(); k++) {
	    Org org = orgList.get(k);

	    List<Person> dpersonList = org.getPersonListRecursively();
	    for (int i = 0; i < dpersonList.size(); i++) {
		Person person = dpersonList.get(i);
		if (!personList.contains(person)) {
		    personList.add(person);
		}
		;
	    }
	}
	return personList;
    }

    public List<Person> getAllRightPerson() {
	List<Person> personList = new ArrayList<Person>();

	List<Person> rightPersonList = this.getRightPersonList();
	List<Person> addPersonList = this.getPersonList();
	List<Person> disablePerson = this.getDisablePersonList();
	for (int k = 0; k < rightPersonList.size(); k++) {
	    Person person = rightPersonList.get(k);
	    if (!personList.contains(person)) {
		personList.add(person);
	    }
	    ;
	}
	for (int k = 0; k < addPersonList.size(); k++) {
	    Person person = addPersonList.get(k);
	    if (!personList.contains(person)) {
		personList.add(person);
	    }
	    ;
	}
	for (int k = 0; k < disablePerson.size(); k++) {
	    Person person = disablePerson.get(k);
	    if (!personList.contains(person)) {
		personList.remove(person);
	    }
	    ;
	}
	return personList;
    }

    public int getTier() {
	return this.tier;
    }

    public void setTier(int tier) {
	this.tier = tier;
    }

    public void setBrief(String brief) {
	this.brief = brief;
    }

    public void setID(String id) {
	ID = id;
    }

    public void setName(String name) {
	this.name = name;
    }

    public void setParentId(String parentId) {
	this.parentId = parentId;
    }

    public int getCachedSize() {
	int size = 0;
	size += CacheSizes.sizeOfString(configCode.getType());

	size += CacheSizes.sizeOfString(ID);
	size += CacheSizes.sizeOfString(name);
	size += CacheSizes.sizeOfString(enName);
	size += CacheSizes.sizeOfString(icon);
	size += CacheSizes.sizeOfString(parentId);
	if (index != null) {
	    size += CacheSizes.sizeOfString(index.toString());
	}
	if (brief != null) {
	    size += CacheSizes.sizeOfString(brief);
	}
	size += CacheSizes.sizeOfList(childIdList);
	size += CacheSizes.sizeOfList(recursiveChildIdList);
	size += CacheSizes.sizeOfList(moduleIdList);
	size += CacheSizes.sizeOfList(recursiveModuleIdList);

	return 0;
    }

    public DbApp clone() {
	DbApp app = new DbApp(this.configCode);
	app.setID(ID);
	app.setIndex(index);
	app.setEnName(enName);
	app.setIcon(icon);
	app.setName(name);
	app.setParentId(parentId);
	app.setTier(tier);
	return app;
    }

    public int compareTo(App o) {
	if (o.getIndex() > this.index) {
	    return 1;
	}
	return 0;
    }

    public Integer getIndex() {
	return index;
    }

    public void setIndex(Integer index) {
	this.index = index;
    }

    public String getEnName() {
	return enName;
    }

    public void setEnName(String enName) {
	this.enName = enName;
    }

    public String getIcon() {
	return icon;
    }

    public void setIcon(String icon) {
	this.icon = icon;
    }

    public ConfigCode getSubSystemId() {
	return configCode;
    }

    public void setSubSystemId(ConfigCode subSystemId) {
	this.configCode = subSystemId;
    }

    public Object getAppIdList() {
	return appIdList;
    }

    public void setAppIdList(Object appIdList) {
	this.appIdList = appIdList;
    }

    public boolean isAppIdList_is_initialized() {
	return appIdList_is_initialized;
    }

    public void setAppIdList_is_initialized(boolean appIdList_is_initialized) {
	this.appIdList_is_initialized = appIdList_is_initialized;
    }

    public boolean isChildIdList_is_initialized() {
	return childIdList_is_initialized;
    }

    public void setChildIdList_is_initialized(boolean childIdList_is_initialized) {
	this.childIdList_is_initialized = childIdList_is_initialized;
    }

    public List<String> getDisablePersonIdList() {
	return disablePersonIdList;
    }

    public void setDisablePersonIdList(List<String> disablePersonIdList) {
	this.disablePersonIdList = disablePersonIdList;
    }

    public boolean isDisablePersonIdList_is_initialized() {
	return disablePersonIdList_is_initialized;
    }

    public void setDisablePersonIdList_is_initialized(boolean disablePersonIdList_is_initialized) {
	this.disablePersonIdList_is_initialized = disablePersonIdList_is_initialized;
    }

 
    public boolean isModuleIdList_is_initialized() {
	return moduleIdList_is_initialized;
    }

    public void setModuleIdList_is_initialized(boolean moduleIdList_is_initialized) {
	this.moduleIdList_is_initialized = moduleIdList_is_initialized;
    }

    public boolean isOrgIdList_is_initialized() {
	return orgIdList_is_initialized;
    }

    public void setOrgIdList_is_initialized(boolean orgIdList_is_initialized) {
	this.orgIdList_is_initialized = orgIdList_is_initialized;
    }

    public List<String> getPersonIdList() {
	return personIdList;
    }

    public void setPersonIdList(List<String> personIdList) {
	this.personIdList = personIdList;
    }

    public boolean isPersonIdList_is_initialized() {
	return personIdList_is_initialized;
    }

    public void setPersonIdList_is_initialized(boolean personIdList_is_initialized) {
	this.personIdList_is_initialized = personIdList_is_initialized;
    }


    public List getRecursiveChildIdList() {
	return recursiveChildIdList;
    }

    public void setRecursiveChildIdList(List recursiveChildIdList) {
	this.recursiveChildIdList = recursiveChildIdList;
    }

    public List getRecursiveModuleIdList() {
	return recursiveModuleIdList;
    }

    public void setRecursiveModuleIdList(List recursiveModuleIdList) {
	this.recursiveModuleIdList = recursiveModuleIdList;
    }

    public boolean isRoleIdList_is_initialized() {
	return roleIdList_is_initialized;
    }

    public void setRoleIdList_is_initialized(boolean roleIdList_is_initialized) {
	this.roleIdList_is_initialized = roleIdList_is_initialized;
    }

    public void setChildIdList(List childIdList) {
	this.childIdList = childIdList;
    }

  

    public void setModuleIdList(List moduleIdList) {
	this.moduleIdList = moduleIdList;
    }

    public void setOrgIdList(List<String> orgIdList) {
	this.orgIdList = orgIdList;
    }

   
    public void setRoleIdList(List<String> roleIdList) {
	this.roleIdList = roleIdList;
    }

}
